package com.yunji.order.command.order;

import com.yunji.common.exception.ServiceException;
import com.yunji.common.utils.Pair;
import com.yunji.order.command.order.impl.OrderCancelCommand;
import com.yunji.order.command.order.impl.OrderCreateCommand;
import com.yunji.order.command.order.impl.OrderPaidCommand;
import com.yunji.order.dto.cmd.OrderCommandDTO;
import com.yunji.order.emuns.OrderStatusEnum;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : peter-zhu
 * @date : 2025/3/7 17:42
 * @description : 订单状态机
 **/
@Component
public class OrderStateMachine {
    private static final Map<Pair<OrderStatusEnum, OrderStatusEnum>, IOrderCommand> MACHINE_COMMAND = new HashMap<>();

    @Resource
    private OrderCreateCommand orderCreateCommand;

//    @Resource
//    private OrderPayCommand orderPayCommand;

    @Resource
    private OrderPaidCommand orderPaidCommand;

    @Resource
    private OrderCancelCommand orderCancelCommand;

    @PostConstruct
    public void init() {
        MACHINE_COMMAND.put(new Pair<>(OrderStatusEnum.WAIT_PAYING, OrderStatusEnum.WAIT_PAYING),orderCreateCommand);
        MACHINE_COMMAND.put(new Pair<>(OrderStatusEnum.WAIT_PAYING, OrderStatusEnum.ORDER_CANCEL), orderCancelCommand);
        //MACHINE_COMMAND.put(new Pair<>(OrderStatusEnum.WAIT_PAYING, OrderStatusEnum.PAID), orderPayCommand);
        MACHINE_COMMAND.put(new Pair<>(OrderStatusEnum.WAIT_PAYING, OrderStatusEnum.PAY_SUCCESS), orderPaidCommand);
        MACHINE_COMMAND.put(new Pair<>(OrderStatusEnum.ORDER_CANCEL, OrderStatusEnum.PAY_SUCCESS), orderPaidCommand);
        //MACHINE_COMMAND.put(new Pair<>(OrderStatusEnum.PAY_SUCCESS, OrderStatusEnum.ORDER_FINISH), null);
    }

    public static Object statusChange(OrderCommandDTO cmd) {
        Pair<OrderStatusEnum, OrderStatusEnum> p = new Pair<>(cmd.getOldStatus(), cmd.getNewStatus());
        IOrderCommand<OrderCommandDTO, ?> machine = MACHINE_COMMAND.get(p);
        if (machine != null)
            return machine.execute(cmd);
        else
            throw new ServiceException(MessageFormat.format("不支持的状态变更: {0}({1}) -> {2}({3}) ",
                    cmd.getOldStatus(), cmd.getOldStatus().getValue(), cmd.getNewStatus(), cmd.getNewStatus().getValue()));
    }
}
